﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;

namespace blackhouse.BlackApart.Data {
    public abstract class AdoApartmentDataAccess : IApartmentDataAccess {

        #region IApartmentDataAccess

        public abstract int SaveApartment(int id, string name, int groupId, int locationId, int numberOfPeople, float areaSize);

        public ApartmentData GetApartment(int apartmentId) {
            return this.ReadApartment(this.GetReaderForApartment(apartmentId));
        }

        public ApartmentData[] GetFreeApartments(DateTime startDate, DateTime endDate, int apartmentGroupId) {
            return this.ReadApartments(GetReaderForApartmentsFree(startDate, endDate, apartmentGroupId));
        }

        public ApartmentData[] GetApartmentsByGroup(int groupId) {
            return this.ReadApartments(GetReaderForApartmentsByGroup(groupId));
        }

        public ApartmentPhotoData[] GetApartmentPhotos(int apartmentId) {
            return this.ReadApartmentPhotos(GetReaderForApartmentPhotos(apartmentId));
        }

        public ApartmentPhotoData[] GetApartmentTypePhotos(int apartmentTypeId, string language) {
            return this.ReadApartmentPhotos(GetReaderForApartmentTypePhotos(apartmentTypeId, language));
        }

        #endregion

        #region Abstracts

        protected abstract IDataReader GetReaderForApartment(int apartmentId);
        protected abstract IDataReader GetReaderForApartmentsFree(DateTime startDate, DateTime endDate, int apartmentGroupId);
        protected abstract IDataReader GetReaderForApartmentsByGroup(int groupId);
        protected abstract IDataReader GetReaderForApartmentPhotos(int apartmentId);
        protected abstract IDataReader GetReaderForApartmentTypePhotos(int apartmentTypeId, string language);

        #endregion

        #region Methods

        private ApartmentData ReadApartment(IDataReader reader) {
            if (reader.Read()) {
                ApartmentData data = ReadApartmentFields(reader);
                reader.Close();
                return data;
            }
            else return default(ApartmentData);
        }

        private ApartmentData[] ReadApartments(IDataReader reader) {
            List<ApartmentData> data = new List<ApartmentData>();
            while (reader.Read()) {
                data.Add(ReadApartmentFields(reader));
            }
            reader.Close();
            return data.ToArray();
        }

        private ApartmentPhotoData[] ReadApartmentPhotos(IDataReader reader) {
            List<ApartmentPhotoData> data = new List<ApartmentPhotoData>();
            while (reader.Read()) {
                data.Add(ReadApartmentPhotoFields(reader));
            }
            reader.Close();
            return data.ToArray();
        }

        private ApartmentData ReadApartmentFields(IDataReader reader) {
            ApartmentData data = new ApartmentData();
            data.Id = Convert.ToInt32(reader["Id"]);
            data.Name = Convert.ToString(reader["Name"]);
            data.AreaSize = Convert.ToSingle(reader["AreaSize"]);
            data.GroupId = Convert.ToInt32(reader["GroupId"]);
            data.LocationId = Convert.ToInt32(reader["LocationId"]);
            data.NumberOfPeople = Convert.ToInt32(reader["NumberOfPeople"]);
            return data;
        }

        private ApartmentPhotoData ReadApartmentPhotoFields(IDataReader reader) {
            ApartmentPhotoData data = new ApartmentPhotoData();
            data.PhotoId = Convert.ToInt32(reader["PhotoId"]);
            data.Category = Convert.ToString(reader["Category"]);
            data.Description = Convert.ToString(reader["Description"]);
            data.PhotoName = Convert.ToString(reader["PhotoName"]);
            data.Sort = Convert.ToInt32(reader["Sort"]);
            return data;
        }

        #endregion

    }
}
